#include <sum_gpio.h>
#include <sum_rcu.h>
#include <sum_usart.h>
#include <sum_wfi.h>
#include <sys_mem.h>
#include <util_trans.h>

#define APB2_FREQ_DEFAULT 8000000

// 开启外部时钟HXTAL
static void _set_hxtal(void) {
	rcu_ctl_16_23_expl_s hxtal_setup = {
		.hxtal_en = 1,
	};
	rcu_setup_hxtal(hxtal_setup);
	do {
		hxtal_setup = rcu_read_hxtal_setup();
	} while (!hxtal_setup.is_hxtal_stable);

	rcu_cfg0_para_s para = {
		.set_sys_clock = RCU_CFG0_SYS_CLOCK_HXTAL,
	};
	rcu_set_cfg_0(para);
}

// RCU中将GPIOA和USART0上电
static void _enable_gpioad_usart0(void) {
	rcu_apb2_s apb2 = {
		.apb2_0_7.GPIOA = 1,
		.apb2_0_7.GPIOD = 1,
		.apb2_8_15.USART0 = 1,
	};
	rcu_apb2_en_di(apb2);
}

// 配置A9为AF输出，A10为浮空输入。
static void _setup_gpafio(void) {
	gpio_ctl_8_15_s ctl_gpioa_8_15 = {
		// A9的配置：低速输出、AF、推挽
		.pin9_ctl = GPIO_OUT_AF_PP_2MHZ,

		// A10的配置：输入、浮空
		.pin10_ctl = GPIO_IN_FLOAT,
	};
	gpio_setup_pin_8_15(GPIOA_Q, ctl_gpioa_8_15);

	// gpio_ctl_0_7_s ctl_gpiod_0_7 = {
	// 	// D0的配置：AF，速度不重要
	// 	.pin0_ctl = GPIO_OUT_AF_PP_2MHZ,

	// 	// D1的配置：AF，速度不重要
	// 	.pin1_ctl = GPIO_OUT_AF_PP_2MHZ,
	// };
	// gpio_setup_pin_0_7(GPIOD_Q, ctl_gpiod_0_7);
}

// 使能USART0本身，以及其发送功能。
static void _enable_usart0_send(void) {
	usart_ctl0_expl_s ctl0 = {
		.trans_en = 1,
		.usart_en = 1,
	};
	usart_setup_0(USART0_Q, ctl0);
}

// 向串口阻塞发送1字节的函数，也是trans_write系列函数的参数。
static void _send(u32_s byte) {
	usart_wb_byte(USART0_Q, byte);
}

__attribute__((noreturn, section(".MAIN"))) void user_main(void) {
	// 未定义全局变量和静态局部变量，因此不需要scatter_load。
	// mem_scatter_load();
	_enable_gpioad_usart0();
	_setup_gpafio();
	_set_hxtal();
	usart_set_baud_rate(USART0_Q, 115200, APB2_FREQ_DEFAULT);
	_enable_usart0_send();

	trans_write_str("HXTAL set success! RCU_CTL_16_23 is 0x", _send);
	rcu_ctl_16_23_expl_s hxtal_setup = rcu_read_hxtal_setup();
	union {
		rcu_ctl_16_23_expl_s e;
		u32_s u;
	} eu = {
		.e = hxtal_setup,
	};
	trans_write_uhex(eu.u, 8, _send);
	trans_write_str(".\n", _send);
	wfi_loop();
}
